using System;
using System.Text;
using System.Security.Cryptography;

/// <summary>
/// Summary description for CryptoLib.
/// </summary>
public class CryptoLib
{
//		/// <summary>
//		/// 
//		/// </summary>
//		public enum Providers:int
//		{
//			/// <summary>
//			/// 
//			/// </summary>
//			DES, 
//			/// <summary>
//			/// 
//			/// </summary>
//			RC2, 
//			/// <summary>
//			/// 
//			/// </summary>
//			Rijndael,
//			/// <summary>
//			/// 
//			/// </summary>
//			TripleDes
//		}

	private SymmetricAlgorithm mCryptoService;
	private string mPasswordKey;
	private CryptoServiceProvider mCryptoType;
	private byte[] _Key;
	//private byte[] mPWDHash;

	/// <summary>
	/// constructor
	/// </summary>
	/// <param name="sKey"></param>
	/// <param name="CryptoType"></param>
	public CryptoLib(string sKey, CryptoServiceProvider CryptoType)
	{
		this.mPasswordKey = sKey;
		this.mCryptoType = CryptoType;			
		InitCrypto();
	}

	private void InitCrypto()
	{
		if (this.mCryptoService == null)
		{
			switch (this.mCryptoType)
			{
				case CryptoServiceProvider.DES :
					this.mCryptoService = new DESCryptoServiceProvider();
					break;
				case CryptoServiceProvider.RC2 :
					this.mCryptoService = new RC2CryptoServiceProvider();
					break;
				case CryptoServiceProvider.Rijndael :
					this.mCryptoService = new RijndaelManaged();
					break;
				case CryptoServiceProvider.TripleDes :
					this.mCryptoService = new TripleDESCryptoServiceProvider();
					break;
			}

			//GetKey();
			this._Key = GetLegalKey(this.mPasswordKey);
			if (this.mCryptoType == CryptoServiceProvider.Rijndael)
			{
				if (this._Key.Length != 16)
				{
					this.mPasswordKey = this.mPasswordKey.Substring(0, 8);
					this._Key = this.GetLegalKey(this.mPasswordKey);
				}
			}
			this.mCryptoService.Key = this._Key; //GetLegalKey(this.mPasswordKey);
			this.mCryptoService.Mode = CipherMode.ECB;
		}
	}

//		private void GetKey()
//		{
//			MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider();
//			mPWDHash = hashmd5.ComputeHash(ASCIIEncoding.ASCII.GetBytes(this.mPasswordKey));
//			hashmd5.Clear();
//			hashmd5 = null;
//		}

	private byte[] GetLegalKey(string Key)
	{
		string sTemp = Key;
		if (mCryptoService.LegalKeySizes.Length > 0)
		{
			int moreSize = mCryptoService.LegalKeySizes[0].MinSize;
			// key sizes are in bits
			if (sTemp.Length * 8 > mCryptoService.LegalKeySizes[0].MaxSize)
				// get the left of the key up to the max size allowed
				sTemp = sTemp.Substring(0, mCryptoService.LegalKeySizes[0].MaxSize / 8);
			else if (sTemp.Length * 8 < moreSize)
				if (mCryptoService.LegalKeySizes[0].SkipSize == 0)
					// simply pad the key with spaces up to the min size allowed
					sTemp = sTemp.PadRight(moreSize / 8, ' ');
				else
				{
					while (sTemp.Length * 8 > moreSize)
						moreSize += mCryptoService.LegalKeySizes[0].SkipSize;

					sTemp = sTemp.PadRight(moreSize / 8, ' ');
				}
		}

		// convert the secret key to byte array
		//return ASCIIEncoding.ASCII.GetBytes(sTemp);
        return UTF8Encoding.UTF8.GetBytes(sTemp);
	}

	/// <summary>
	/// Ham dung de encrypt mot chuoi
	/// </summary>
	/// <param name="s"></param>
	/// <returns></returns>
	public string Encrypt(object s)
	{
		string tmp = (s == null) ? string.Empty : s.ToString().Trim();
		if (tmp.Length > 0)
		{
			byte[] buff;
			InitCrypto();
			buff = UTF8Encoding.UTF8.GetBytes(tmp);
			try
			{
				return Convert.ToBase64String(mCryptoService.CreateEncryptor().TransformFinalBlock(buff, 0, buff.Length));
			}
			catch
			{
				return string.Empty;
			}
		}
		return tmp;
	}

	/// <summary>
	/// Ham descrypt 1 chuoi da bi encrypte
	/// </summary>
	/// <param name="s"></param>
	/// <returns></returns>
	public string Decrypt(object s)
	{
		string tmp = (s == null) ? string.Empty : s.ToString().Trim();
		if (tmp.Length > 0)
		{
			byte[] buff;
			buff = Convert.FromBase64String(tmp);
			InitCrypto();
			try
			{
				return UTF8Encoding.UTF8.GetString(mCryptoService.CreateDecryptor().TransformFinalBlock(buff, 0, buff.Length));
			}
			catch
			{
				return string.Empty;
			}
		}
		return tmp;
	}

	/// <summary>
	/// ham decrypt mot chuoi da duoc encrypt va dua qua query string (web)
	/// </summary>
	/// <param name="s"></param>
	/// <returns></returns>
	public string DecryptWeb(object s)
	{
		string tmp = (s == null) ? string.Empty : s.ToString().Replace(" ", "+");
		return Decrypt(tmp);
	}
}
